'''
Created on 25 Oct 2012

@author: quirino.brizi
'''

from org.codesketch.loadit.configuration.domain import Server, Target, Parameter, \
    Test, Configuration, Script, Address
import xml.etree.ElementTree as ET
from org.codesketch.loadit.utils import load

class XmlConfigurationParser():
    '''
    Parser the XML configuration file.
    '''
    
    @staticmethod
    def parse(path):
        '''
        Parse the configuration file located at the given path
        '''
        # Reads the XML file and get the root element
        tree = ET.parse(load(path))
        root = tree.getroot()
        # get server and test node
        server = root.find('server');
        test = root.find('test')
        script = root.find('script')
        
        return Configuration(XmlConfigurationParser.__server(server), XmlConfigurationParser.__test(test), XmlConfigurationParser.__script(script))
        
    @staticmethod
    def __server(element) :
        '''
        Build a server object from XML server node
        @param element: the XML server node
        @return: a {@link Server} object
        '''
        if element is not None :
            address = element.get('address')
            port = int(element.get('port'))
            secure = element.find('secure').text == 'true'
            username = element.find('username').text
            password = element.find('password').text
            return Server(address, secure, username, password, port)
        else :
            raise ValueError('Server element cannot be none')
    
    @staticmethod
    def __test(element):
        '''
        Build a test object from XML test node
        @param element: the XML test node
        @return: a {@link Test} object
        '''
        if element is not None :
            # retrieve specific test information
            identifier = element.get('id')
            duration = int(element.find('duration').text)
            sampling = int(element.find('sampling').text)
            # retrieve target information
            addresses = []
            target = element.find('target')
            for address in target.findall('address') :
                protocol = address.get('protocol')
                host = address.find('host').text
                port = int(address.find('port').text)
                path = address.find('path').text
                username = address.find('username').text
                password = address.find('password').text
                params = {}
                for param in address.findall('property') :
                    params[param.get('key')] = param.text
                
                addresses.append(Address(protocol, host, port, path, username, password, params))
            
            target = Target(addresses)
#            address = element.find('target').get('address')
#            port = int(element.find('target').get('port'))
#            secure = element.find('target').find('secure').text == 'true'
#            username = element.find('target').find('username').text
#            password = element.find('target').find('password').text
#            target = Target(address, secure, username, password, port)
            
            # build the test object
            return Test(identifier, duration, sampling, target)
        else :
            raise ValueError('Test element cannot be none')
    
    @staticmethod      
    def __script(element):
        '''
        Build a script object from XML script node
        @param element: the XML script node
        @return: a {@link Script} object 
        '''
        
        if element is not None :
            clazz = element.get('class')
            # retrieve parameters
            params = []
            for param in element.findall('property') :
                params.append(Parameter(param.get('key'), param.text))
                
            return Script(clazz, params)
        else :
            raise ValueError('Script element cannot be none')
        